package com.tianqi.common.utils;

import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.tianqi.common.enums.EightCharactersReqTypeEnum;
import com.tianqi.common.exception.ApiException;
import com.tianqi.modules.pms.dto.request.DateTimeReq;
import com.tianqi.modules.pms.dto.response.TimeConvertResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 阴历工具
 *
 * @author zhangzedi
 * @date 2023/8/20 16:42
 **/
@Slf4j
@Component
public class LunarDateUtil {

	@Autowired
	private TimeUtils timeUtils;

	/**
	 * 格式化为阴历时间
	 *
	 * @param dateReqDTO
	 * @return
	 */
	public Lunar formatEightChar(DateTimeReq dateReqDTO) {
		
		// 声明生辰时间lunar对象,以及占卜时间lunar
		Lunar lunar;
		try {
			if (EightCharactersReqTypeEnum.SOLAR.getCode().equals(dateReqDTO.getDateType())) {
				// 入参是阳历日期
				if (StringUtils.isEmpty(dateReqDTO.getDateStr())) {
					throw new ApiException("阳历时间不能空");
				}
				String dateString = dateReqDTO.getDateStr();
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date date = format.parse(dateString);
				// 计算真太阳时
				if (dateReqDTO.getTrueSolarTime() != null && dateReqDTO.getTrueSolarTime()) {
					if (StringUtils.isEmpty(dateReqDTO.getLocation())) {
						throw new ApiException("计算真太阳时地点不能为空");
					}
					TimeConvertResultDTO timeConvertResultDTO = timeUtils.getTimeConvert(date,
							dateReqDTO.getLocation());
					date = timeConvertResultDTO.getDate();
					dateReqDTO.setLatAndLon(timeConvertResultDTO.getLocation());
					dateReqDTO.setDateStr(format.format(date));
				}
				// 实例化阳历
				Solar solar = Solar.fromDate(date);
				// 转阴历
				return solar.getLunar();

			} else if (EightCharactersReqTypeEnum.LUNAR.getCode().equals(dateReqDTO.getDateType())) {
				// 入参是阴历类型
				if (StringUtils.isEmpty(dateReqDTO.getDateStr())) {
					throw new ApiException("阴历日期不能为空");
				}
				String[] dateString = dateReqDTO.getDateStr().split(" ")[0].split("-");
				String[] timeString = dateReqDTO.getDateStr().split(" ")[1].split(":");
				int lunarYear = Integer.parseInt(dateString[0]);
				int lunarMonth = Integer.parseInt(dateString[1]);
				int lunarDay = Integer.parseInt(dateString[2]);
				int hour = Integer.parseInt(timeString[0]);
				int minute = Integer.parseInt(timeString[1]);
				int second = Integer.parseInt(timeString[2]);
				// 判断是否闰月
				if (dateReqDTO.getTrueLeapMonth() != null && dateReqDTO.getTrueLeapMonth()) {
					lunar = Lunar.fromYmdHms(lunarYear, -lunarMonth, lunarDay, hour, minute, second);
				} else {
					lunar = Lunar.fromYmdHms(lunarYear, lunarMonth, lunarDay, hour, minute, second);
				}

				//计算真太阳时
				if (dateReqDTO.getTrueSolarTime() != null && dateReqDTO.getTrueSolarTime()) {
					if (StringUtils.isEmpty(dateReqDTO.getLocation())) {
						throw new ApiException("计算真太阳时地点不能为空");
					}
					// 转阳历
					Solar solar = lunar.getSolar();
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					Date date = format.parse(solar.toYmdHms());
					TimeConvertResultDTO timeConvertResultDTO = timeUtils.getTimeConvert(date,
							dateReqDTO.getLocation());
					date = timeConvertResultDTO.getDate();
					dateReqDTO.setLatAndLon(timeConvertResultDTO.getLocation());
					dateReqDTO.setDateStr(format.format(date));
					// 实例化
					Solar solarresult = Solar.fromDate(date);
					// 转阴历-重新赋值
					return solarresult.getLunar();
				} else if (EightCharactersReqTypeEnum.GANZHI.getCode().equals(dateReqDTO.getDateType())) {
					// 入参类型是干支历时,解析成阳历时间-可能有多个时间，取最后一个
					List<Solar> solars = Solar.fromBaZi(dateReqDTO.getYearInGanZhi(),
							dateReqDTO.getMonthInGanZhi(),
							dateReqDTO.getDayInGanZhi(), dateReqDTO.getTimeInGanZhi(),
							1, 1800);
					return solars.get(solars.size() - 1).getLunar();
				} else {
					throw new ApiException("入参时间类型不能为空");
				}
			} else {
				throw new ApiException("类型不对请重新填写");
			}
		} catch (Exception e) {
			log.error("格式化时间为干支历报错,{}", e.getMessage());
			throw new ApiException("格式化时间报错");
		}
	}
}
